////////////////////////////////////////////////////////////////////////////////
/*
 *--------------- 客户端表单通用验证CheckForm(oForm) -----------------
 * 功能:通过正则表达式实现通用验证所有的表单元素.
 * 使用:
 *　<form name="form1" onsubmit="return CheckForm(this)">
 *　　    <input type="text" name="name" check="notBlank" needInput="true" showName="用户姓名">
 *　　    <input type="submit">
 *　</form>
 *
 *  play frame 使用:
 *  play frame can leave out the showName, normal get the showName from [element].parent().siblings(":first").html()
 @inputText(roleform("name"),'_label -> Messages("role.name"),'data_check->"isString(2,30)",'showName->"")

 <div class="form-group">
 <label class="control-label" for="name">role.name</label>
 <div class="controls">
 <input id="name" type="text" needinput="true" check="isString(2,30)" value="" name="name">
 <span class="help-inline">最長長度: 30, 最短長度: 2, 必填</span>
 </div>
 </div>

 * 通过对needInput的属性设置true或false，断定该项是否必填.默认为""等同于true
 * showName为alert时候要显示的对象.
 * check的属性设置重点说明如下:
 *      对于不带参数的规则，可直接设置规则名，如notBlank或者notBlank().
 *      对于带参数的规则，需要设置对应的规则参数，如isDate('YYYY-MM-DD').
 *      对于本JS文件未提供的正则类型判定，可自行设置正则表达式验证，如验证三到五位的字符，设置reg('^\\S{3,5}$') .
 *      可给check设置多个规则，各个规则之间使用";"隔开，如"不能含有空格，且字数不能超过10",设置"notBlank;isString('#',10)".
 * 规则函数的设定，有两种方式,说明如下:
 *      1.正则验证，返回数组rt，rt[0]为对应的正则表达式，rt[1]为对应要警告的语句.
 *      //2.普通的判断function，返回false或true，函数体中通过this.value和this.showName获取页面数据，自行判定value的合法性.
 *       (修改为)2.普通的判断function，返回数组rt，rt[0]false或true为验证结果, 当rt[0]为false时,rt[1]的内容为对应要警告的语句;否则rt[1]为空
 *
 *       notBlank()             不能为空,且不能含有空格!
 needInput()            不能为空
 isDate(fmt)            fmt : YYYY-MM-DD  yyyy-mm-dd
 isString(min,max)      如min设为"'#'",表示字数不能大于max
 如max设为"'#'",表示字数不能小于min
 最小和最大值
 strStartsWith(str)     以什么字符开头
 isContains(str)        包含什么字符
 strEndsWith(str)       以什么字符结尾
 eqEleValue(orig,target)   判定与某个元素值是否相等 ,比如:确认密码的时候使用
 isEmail()              应为正确的EMAIL格式
 onlyZh()           应输入中文
 onlyEn()       只能输入英文
 enOrNum()          只能输入英文和数字,且不能有空格！
 isInt(type)        type: 0+  应输入非负整数  type:+ 应输入正整数  type:-0 应输入非正整数 type:- 应输入负整数 type:其它 应输入整数值
 setNumber(min,max)     如min设为"'#'",表示不能大于max  如max设为"'#'",表示不能小于min
 isPhone()          应输入正确的电话号码格式
 isMobile()         正确的手机号码格式
 isUrl()        正确的URL（必须以http(s)://开头）
 isZip()            正确的编码格式
 select(num)            目标至少需要选择(通常用于select-multiple/checkbox)
 reg(EXP)                EXP为正则表达式   reg('^\\S{3,5}$')
 *--------------- 客户端表单通用验证CheckForm(oForm) -----------------
 */
///////////////////////////////////////////////////////////////////////////////////
    var value="",showName="";

    function CheckForm(oForm){
        var elements =  $(oForm).find("[data_check]");
        for(var i=0;i<elements.length;i++){
            setNomal(elements[i]);
        }
        for(var i=0;i<elements.length;i++){
            //console.debug(elements[i]);
            if( (!validate(elements[i]))){
                return false;
            }
        }
        return true;
    }

    function validate(ele){

        //取得表单的值,用通用取值函数            
        var sVal = GetValue(ele);
        this.value = sVal;
        
        this.showName=$(ele).attr("showname");
        //play frame check
        if(this.showName==null || this.showName==undefined){
            var lableValue = $(ele).parents(".form-group").find("label").html();
            this.showName = "“"+lableValue+"”";
        }else{
            this.showName="“"+this.showName+"”";
        }

        var checkArr = $(ele).attr("data_check").split(";");
        for (var i=0;i<checkArr.length ;i++ ){
            if(checkArr[i]=="")
                continue;

            //取得验证的规则函数
            var sReg = "";
            if( $(ele).attr("data_check")){
                try{sReg = executeFunc(checkArr[i]);
                }catch(e){
                    //alert(e+"使用错误:类型'"+checkArr[i]+"'对应的验证规则函数未定义！");//--------------------
                    showObject(ele,e+"使用错误:类型'"+checkArr[i]+"'对应的验证规则函数未定义！");
                    return false;
                    //sReg = ele.check;
                }
            }
            if(sReg==null||sReg=="undefined"){continue;}
            if(sReg[0]==false||sReg[0]=="false"){showObject(ele,sReg[1]);return false;}
            if(sReg[0]=="" || sReg[0]==true){continue;}

            //判定是否符合正则表达式
            if(!regValidate(this.value,sReg[0])){//验证不通过,弹出提示warning
                var msg = this.showName;
                if($(ele).attr("data_check")){
                    try{
                        msg += sReg[1];
                    }catch(e){
                        msg += "格式不正确！";
                    }
                }
                //alert(msg);//-----------------------------
                showObject(ele,msg);//该表单元素取得焦点,用通用返回函数
        　　　　 return false;
            }
        }
        return true;
    }

　　//通用取值函数分三类进行取值
　　//文本输入框,直接取值el.value
　　//单多选,遍历所有选项取得被选中的个数返回结果"00"表示选中两个
　　//单多下拉菜单,遍历所有选项取得被选中的个数返回结果"0"表示选中一个
　　function GetValue(el){
　　　　//取得表单元素的类型
　　　　var sType = $(el).attr("type");
        //如果没有type类型，就它自身标签
       if(sType==null || sType=="undefined"){sType = $(el).get(0).tagName.toLowerCase();}
　　　　switch(sType){
　　　　　　case "text":
　　　　　　case "hidden":
　　　　　　case "password":
　　　　　　case "file":
　　　　　　case "textarea": return $(el).val();
　　　　　　case "checkbox":
　　　　　　case "radio": return GetValueChoose(el);
    　　　　case "select": return GetValueSel(el)
　　　　　　case "select-one":
　　　　　　case "select-multiple": return GetValueSel(el);
　　　　}
　　　　//取得radio,checkbox的选中数,用"0"来表示选中的个数,我们写正则的时候就可以通过0{1,}来表示选中个数
　　　　function GetValueChoose(el){
　　　　　　var sValue = "";
　　　　　　//取得第一个元素的name,搜索这个元素组
    　　    var obj= $(el).parent().find("input:checked[name='"+$(el).attr("name")+"']");
　　　　　　for(var i=0;i<obj.length;i++)
　　　　　　　　sValue += "0";
　　　　　　return sValue;
　　　　}
　　　　//取得select的选中数,用"0"来表示选中的个数,我们写正则的时候就可以通过0{1,}来表示选中个数
　　　　function GetValueSel(el){
　　　　　　var sValue = "";
　　　　　　var length = $(el).find("option:selected[value!='']").length;
            for(var i=0; i<length;i++)
                sValue += "0";
　　　　　　return sValue;
　　　　}
　　}


    function executeFunc(name){
        if(name.indexOf("(")==-1){
            return eval(name+"()");
        }else{
            return eval(name);
        }
    }
    
    //去除空格
    function trim(value){
        return value.replace(/(^\s*)|(\s*$)/g, "");
    }

    //判定某个值与表达式是否相符
    function regValidate(value,sReg){
        //字符串->正则表达式,不区分大小写
        var reg = new RegExp(sReg ,"i");
        if(reg.test(value)){
            return true;
        }else{
            return false;
        }
    }
    
    
    //判定某个数值与某个验证函数是否相符
    function checkValue(obj,value,func){
        this.value = value;
        var rt = "";
        try{
            rt = executeFunc(func);
        }catch(e){
            //alert(e+"使用错误:函数"+func+"未定义！");//--------------------------------------
            showObject(obj,e+"使用错误:函数"+func+"未定义！");
            return false;
            //sReg = ele.check;
        }
        
        if(rt==null||rt=="undefined"){
                return true;
        }
        if(rt==false||rt=="false"){
    　　　　return false;   
        }
        //验证表达式
        var check = regValidate(value,rt[0]);
        if(!check&&this.showName!=""){
            //alert(this.showName+rt[1]);//--------------------------------------           
            showObject(obj,this.showName+rt[1]);
        }
        return check;
    }

    //检查某个元素与某个验证函数是否相符,需要传入元素的ID
    function checkElement(id,func,showName){
        var obj = document.getElementById(id);
        if(obj==null||obj=="undefined"){
            //alert("对应id:"+id+"的元素不存在！");//----------------------------------------
            return false;
        }
        if(showName!=null){
            this.showName = "“"+showName+"”";
        }else{
            this.showName = "";
        }

        var value = obj.value;
        var check = checkValue(obj,value,func);
        return check;
    }

    //检查某个对象(checkbox/select-multiple)至少选择个数,需要传入元素的NAME
    function checkSelectByID(name,num,showName){
        //console.debug(name);
       //console.debug( name.options);

        var obj = $("#"+name) ;
        var len =obj.find("option:selected[value!='']").length;

        if(showName!=null){
            this.showName = "“"+showName+"”";
        }else{
            this.showName = "";
        }

        var check = checkValue(obj,GetValue(obj[0]),"select("+num+")");
        return check;
    }
    
    //获取某个元素的值
    function elementValue(id){
        var obj = document.getElementById(id);
        if(obj==null||obj=="undefined"){
            return "";
        }
        return obj.value;
    }

    window.onhelp = function() {
          logPanel.style.display=logPanel.style.display=='none'?"block":"none";
          return false;
    }

    // document.write("<div id=logPanel style='display:none'>"+
    //     "<button onclick=\"logPanel_log.innerHTML='';\">clear</button>&nbsp;"+
    //     "<button onclick=\"logPanel_log.innerHTML+='<hr>';\">HR</button>"+
    //     "<div id='logPanel_log'></div></div>");

//////////////////////////////////验证规则定义////////////////////////////////
    
    function reg(sReg){
        var rt = new Array();
        rt[0] = sReg;
        rt[1] = "格式不匹配正则表达式:"+sReg;
        return rt;
    }

    function notBlank(){
        var rt = new Array();
        rt[0] = "^\\S+$";
        rt[1] = "不能为空,且不能含有空格!"; 
        return rt;
    }
    
    function needInput(){
        var rt = new Array();
        rt[0] = "^\\S";
        rt[1] = "不能为空!"
        return rt;
    }

    function isDate(fmt){
        var regex = new Array("-",".","/");
        var regex0 = "";
        for (var i=0;i<regex.length ;i++ ){
            if(fmt.indexOf(regex[i])!=-1){
                regex0 = regex[i];
                break;
            }
        }
        var y = 0;
        var m = 0;
        var d = 0;
        var number = new Array(0,0,0);
        var ch = '';
        var index = 0;
        for (var i=0;i<fmt.length ;i++ )
        {
            if(ch==''||fmt.charAt(i)==ch){
                number[index] = number[index]+1;
            }else if(fmt.charAt(i)!=regex0){
                index++;
                number[index] = number[index]+1;
            }
            ch = fmt.charAt(i);
            if(fmt.charAt(i)=='Y'||fmt.charAt(i)=='y'){
                y++;
            }
            if(fmt.charAt(i)=='M'||fmt.charAt(i)=='m'){
                m++;
            }
            if(fmt.charAt(i)=='D'||fmt.charAt(i)=='d'){
                d++;
            }
        }
        
        var rt = new Array();
        var sreg = "";
        for(i in number){
            if(number[i]!=0){
                if(sreg!=""){
                    sreg += regex0; 
                }
                sreg += "\\d{"+number[i]+"}"; 
            }
        }
        sreg = "^"+sreg+"$";
        rt[0] = sreg;
        rt[1] = "格式应为"+fmt;
        return rt;
    }
    
    /**
     * 字符串判定
     * 如min设为"'#'",表示字数不能大于max
     * 如max设为"'#'",表示字数不能小于min
     */
    function isString(min,max){
        var rt = new Array();
        if(min==null&&max==null){
            rt[0] = "";
            rt[1] = "";

            return rt;
        }
        if(max==null)
            max=min;
        if(min=="#"&&max=="#"){
            //任意字符
            rt[0] = "[\\S|\\s]";
            rt[1] = "";
            return rt;
        }
        if(min=="#"){
            rt[0] = "^[\\S|\\s]{0,"+max+"}$"; 
            rt[1] = "字数不能大于"+max;
            return rt;
        }
        if(max=="#"){
            rt[0] = "^[\\S|\\s]{"+min+",}$";
            rt[1] = "字数不能小于"+min;
            return rt;
        }
        rt[0] = "^[\\S|\\s]{"+min+","+max+"}$"; 
        if(min==max){
            rt[1] = "字数应为"+min+"个！";
        }else{
            rt[1] = "字数介于"+min+"和"+max+"之间！";
        }
        return rt;
    }

    function strStartsWith(str){
        var rt = new Array();
        if(this.value.indexOf(str)!=0){
            //alert(this.showName+"必须以字符‘"+str+"’开头！");
            //return false;
            rt[0]=false;
            rt[1]=this.showName+"必须以字符‘"+str+"’开头！";
            return rt;
        }
    }

    function isContains(str){
        var rt = new Array();
        if(this.value.indexOf(str)==-1){
            //alert(this.showName+"必须包含字符‘"+str+"’！");
            //return false;
            rt[0]=false;
            rt[1]=this.showName+"必须包含字符‘"+str+"’！";
            return rt;
        }
    }
    
    //判定与某个元素值是否相等 ,比如:确认密码的时候使用
    function eqEleValue(orig,target){
        var rt = new Array();
        if( $(orig).val() != $(target).val()){
            rt[0]=false;
            rt[1]=$(orig).attr("showName") + "必须与" +"“"+ $(target).attr("showName") +"“"+"的值相同！";
            return rt;
        }
    }
    
    function strEndsWith(str){
        var rt = new Array();
        if(this.value.lastIndexOf(str)+str.length!=this.value.length){
            //alert(this.showName+"必须以字符‘"+str+"’结束！");
            //return false;
            rt[0]=false;
            rt[1]=this.showName+"必须以字符‘"+str+"’结束！";
            return rt;
        }
    }
    
    //判断email
    function isEmail(){
        var rt = new Array();
        rt[0] = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
        rt[1] = "应为正确的EMAIL格式！";
        
        return rt;
    }
    
    //只能输入中文
    function onlyZh(){
        var rt = new Array();
        rt[0] = "^[\u0391-\uFFE5]+$";
        rt[1] = "应输入中文！";
        return rt;
    }
    
    //只可输入英文
    function onlyEn(){
        var rt = new Array();
        rt[0] = "^[A-Za-z]+$";
        rt[1] = "只能输入英文！";
        return rt;
    }
    
    function enOrNum(){
        var rt = new Array();
        rt[0] = "^[A-Za-z0-9]+$";
        rt[1] = "只能输入英文和数字,且不能有空格！";
        
        return rt;
    }

    /**
     * 整数的判定
     * @param type
     *      为空      任意整数
     *      '0+'    非负整数
     *      '+'     正整数
     *      '-0'    非正整数
     *      '-'     负整数
     */
    function isInt(type){
        var rt = new Array();
        if(type=="0+"){
            rt[0] = "^\\d+$";
            rt[1] = "应输入非负整数!";
        }else if(type=="+"){
            rt[0] = "^\\d*[1-9]\\d*$";
            rt[1] = "应输入正整数!";
        }else if(type=="-0"){
            rt[0] = "^((-\\d+)|(0+))$";
            rt[1] = "应输入非正整数!";
        }else if(type=="-"){
            rt[0] = "^-\\d*[1-9]\\d*$";
            rt[1] = "应输入负整数!";
        }else{
            rt[0] = "^-?\\d+$";
            rt[1] = "应输入整数值！";
        }
        return rt;
    }

    /**
     * 浮点数的判定
     * @param type
     *      为空      任意浮点数
     *      '0+'    非负浮点数
     *      '+'     正浮点数
     *      '-0'    非正浮点数
     *      '-'     负浮点数
     */
    function isFloat(type){
        var rt = new Array();
        if(type=="0+"){
            rt[0] = "^\\d+(\.\\d+)?$";
            rt[1] = "应输入非负浮点数!";
        }else if(type=="+"){
            rt[0] = "^((\\d+\\.\\d*[1-9]\\d*)|(\\d*[1-9]\\d*\\.\\d+)|(\\d*[1-9]\\d*))$";
            rt[1] = "应输入正浮点数!";
        }else if(type=="-0"){
            rt[0] = "^((-\\d+(\.\\d+)?)|(0+(\\.0+)?))$";
            rt[1] = "应输入非正浮点数!";
        }else if(type=="-"){
            rt[0] = "^(-((\\d+\\.\\d*[1-9]\\d*)|(\\d*[1-9]\\d*\\.\\d+)|(\\d*[1-9]\\d*)))$";
            rt[1] = "应输入负浮点数!";
        }else{
            rt[0] = "^(-?\\d+)(\\.\\d+)?$";
            rt[1] = "应输入浮点数值！如：100.00";
        }
        return rt;
    }
    
    /**
     * 数字大小判定
     * 如min设为"'#'",表示不能大于max
     * 如max设为"'#'",表示不能小于min
     */
    function setNumber(min,max){
        var rt = new Array();
        if(!regValidate(this.value,"^(-?\\d+)(\\.\\d+)?$")){
            //alert(this.showName+"应输入数字！");
            //return false;
            rt[0]=false;
            rt[1]= this.showName+"应输入数字！"
            return rt;
        }
        if(min==null&&max==null){
            //任意数字,不判定范围
            return isFloat();
        }
        if(max==null)
            max=min;

        if(min=="#"&&max=="#"){
            //任意数字,不判定范围
            return isFloat();
        }
        if(min=="#"){
            if(this.value>max){
                //alert(this.showName+"不能大于"+max);  
                //return false;
                rt[0]= false;
                rt[1]= this.showName+"不能大于"+max;
                return rt;
            }
        }
        if(max=="#"){
            if(this.value<min){
                //alert(this.showName+"不能小于"+min);  
                //return false;
                rt[0]= false;
                rt[1]= this.showName+"不能大于"+min;
                return rt;
            }
        }
        if(this.value<min||this.value>max){
            if(min==max){
                //alert(this.showName+"的值应为"+min);  
                rt[0]= false;
                rt[1]= this.showName+"的值应为"+min;
            }else{
                //alert(this.showName+"应介于"+min+"和"+max+"之间！");
                rt[0]= false;
                rt[1]= this.showName+"应介于"+min+"和"+max+"之间！";               
            }
            //return false;
            return rt;
        }
        rt[0]=true;
        rt[1]='';
        return rt;
    }

    function isPhone(){
        var rt = new Array();
        //rt[0] = "^((\\(\\d{2,3}\\))|(\\d{3}\\-))?(\\(0\\d{2,3}\\)|0\\d{2,3}-)?[1-9]\\d{6,7}(\\-\\d{1,4})?$";
        rt[0] = "^((\\(\\d{2,3}\\))|(\\d{3}))?(\\(0\\d{2,3}\\)|0\\d{2,3})?[1-9]\\d{6,7}(\\-\\d{1,4})?$";
        rt[1] = "应输入正确的电话号码格式！";
        return rt;
    }

    function isMobile(){
        var rt = new Array();
        rt[0] = "1[3|4|5|8][0-9]\\d{8}$";
        rt[1] = "应输入正确的手机号码格式！";
        return rt;
    }

    function isUrl(){
        var rt = new Array();
        rt[0] = "^http[s]?:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\\?%\\-&_~`@[\\]\\':+!]*([^<>\"\"])*$";
        rt[1] = "应输入正确的URL（必须以http(s)://开头）！";
        return rt;
    }

    function isZip(){
        var rt = new Array();
        rt[0] = "^[1-9]\\d{5}$";
        rt[1] = "应输入正确的编码格式！";
        return rt;
    }

    //目标至少需要选择(通常用于select-multiple/checkbox)
    function select(num){
        var rt = new Array();
        rt[0] = "^0{"+num+",}$";
        rt[1] = "应至少选择"+num+"项！";
        return rt;
    }
    
    function setNomal(targetObj){
        $(targetObj).parent().parent().removeClass("has-error");
        $(targetObj).parent().removeClass("has-error");
        $(targetObj).popover("destroy");
    }
    
    //显示提示信息
    function showObject1(targetObj,infoText){
       // console.debug(infoText);
        $(targetObj).attr("rel","popover");
        //$(targetObj).attr("data-title","信息出错");
        //$(targetObj).attr("data-content",infoText);
        //$(targetObj).attr("data-delay",{show: 100, hide: 100 });
        $(targetObj).parents(".form-group").addClass("has-error");
        $(targetObj).popover({selector: '[rel="popover"]',trigger:'manual', title: '信息出错',content:infoText,delay: {show: 100, hide: 100 }});
        $('[rel="popover"]').popover("show");
        $('[rel="popover"]').click(function(){$(this).popover("hide")})
        $(".popover.fade.right.in").click(function(){
            if($(this).attr("id")==null)
                $(this).hide();
        })
        $(".popover.fade.right.in").addClass("col-sm-5");
        //$(targetObj).popover("show");
        setTimeout(function(){$(targetObj).popover("destroy");},10000);
        return true;
    }
    
  //显示提示信息
    function showObject(targetObj,infoText){
       // console.debug(infoText);
        $(targetObj).attr("rel","popover");
        if($(targetObj).attr("isDate")=="true"){
        	$(targetObj).parent().after("<div class='alert alert-warning infotext'>"+infoText+"</div>");
        }else{
        	$(targetObj).after("<div class='alert alert-warning infotext'>"+infoText+"</div>");
        }
        $(".alert.alert-warning.infotext").click(function(){
                $(this).hide();
        })

        //$(targetObj).popover("show");
        setTimeout(function(){$(".alert.alert-warning.infotext").hide();},10000);
        return true;
    }

    function showObjectInfo(targetObj,infoText){
        // console.debug(infoText);
        $(targetObj).attr("rel","popover");
        //$(targetObj).attr("data-title","信息出错");
        //$(targetObj).attr("data-content",infoText);
        //$(targetObj).attr("data-delay",{show: 100, hide: 100 });
       // $(targetObj).parents(".form-group").addClass("has-error");
        $(targetObj).popover({selector: '[rel="popover"]',trigger:'manual', title: '信息出错',content:infoText,delay: {show: 100, hide: 100 }});
        $('[rel="popover"]').popover("show");
        $('[rel="popover"]').click(function(){$(this).popover("hide")})
        //$(targetObj).popover("show");
        $(".popover.fade.right.in").click(function(){
            if($(this).attr("id")==null)
                $(this).hide()
        })
        setTimeout(function(){$(targetObj).popover("destroy");},10000);
        $(targetObj).click(function(){
            $(targetObj).popover("destroy");
        });
        return true;
    }